<template>
  <div class="hc-file-preview-wrapper" :style="{width: width, height: height}" v-loading="loading">
    <!-- 预览文件的地方（用于渲染） -->
    <!-- pdf -->
    <div class="preview-wrapper" v-if="fileType == 'docx' || fileType == 'doc'">
      <pdf ref="pdf" class="canvasWrapper" type="canvas" v-for="i in pdfObj.numPages" :key="i" :src="pdfObj.pdfUrl" :page="i"></pdf>
    </div>
    <div class="preview-wrapper" v-if="fileType == 'pdf'">
      <iframe :src="pdfObj.pdfUrl" frameborder="0" :style="{ height: '100%', width: '100%' }"></iframe>
    </div>
    <!-- excel -->
    <div class="preview-wrapper" v-else-if="fileType == 'xls' || fileType == 'xlsx'">
        <ExcelPreview ref="excelPreview" :fileUrl="fileUrl" :fileType="fileType" :styles="{ height: 'calc(100vh - 56px)' }" />
    </div>
    <!-- ofd预览 -->
    <div class="preview-wrapper" v-else-if="fileType == 'ofd0'">
        <OfdPreview ref="OfdPreview" :url="fileUrl" />
    </div>
    <!-- 音频 -->
    <div class="preview-wrapper" v-else-if="isAudioFile('.' + fileType)">
      <audio controls :src="fileUrl">
      </audio>
    </div>
    <!-- 视频 -->
    <div class="preview-wrapper" v-else-if="isVideoFile('.' + fileType)" >
      <video width="100%" height="100%" controls :src="fileUrl">
      </video>
    </div>
    <!-- 图片 -->
    <div class="preview-wrapper img-box" v-else-if="isImgFile('.' + fileType)">
      <el-image style="width: 300px;" :src="fileUrl" fit="contain" :preview-src-list="[fileUrl]">
      </el-image>
    </div>
    <!-- 文本类型 -->
    <div class="preview-wrapper" v-else-if="isTextFile('.' + fileType)">
        <monaco-editor v-model="codeValue"
                       :language="getFileLanguage(fileName)"
                       theme="vs"
                       :options="{
                           fontSize: 14,
                          lineNumbers: 'on',
                          minimap: { enabled: true },
                          scrollBeyondLastLine: false,
                          automaticLayout: true
                       }"
        />
    </div>
    <!-- 无法预览 -->
    <div v-else class="no-preview preview-wrapper hc-min-title">该文件类型无法在线预览，请下载后再打开</div>
  </div>
</template>


<script>
import {isImgFile, isVideoFile, isAudioFile, isTextFile, buildPDFPreviewUrl} from "../utils/index";
import
{
    getOpenDownloadUrl,
} from "hc-core/api/common/attachment";
import OfdPreview from "hc-core/components/OfdPreview";
import request from '@/utils/request'
import pdf from 'vue-pdf'
import Codemirror from "./codemirror/index.vue";
// import jsonlint from 'jsonlint';
// window.jsonlint = jsonlint;
import * as monaco from 'monaco-editor'
// 文件预览组件
export default {
  name: "filePreview",
  components: {
      MonacoEditor:() => import("monaco-editor-vue"),
      Codemirror,
      pdf,
      ExcelPreview:() => import("hc-core/components/ExcelPreview.vue"),
      OfdPreview,
  },
  props: {
    // 文件类型
    fileType: {
      type: String,
    },
    // 文件下载地址
    fileUrl: {
      type: String
    },
    // 文件名称
    fileName:{
      type: String
    },
    width: {
      type: String
    },
    height: {
      type: String
    }
  },
  data()
  {
    return {
      loading: false,
      // 文件内容
      codeValue: "",
      //刷新key
      refreshCodemirrorKey: 0,
      // pdf对象
      pdfObj: {
        pdfUrl: null,
        numPages: 1
      },
      languageList: ['javascript', 'typescript', 'html', 'css', 'less', 'scss', 'json', 'markdown', 'vue', 'python', 'java', 'xml', 'sql'],
    }
  },
  mounted()
  {
    // 注册 Monaco Editor 语言
    this.languageList.forEach((preLang) => {
        monaco.languages.register({ id: preLang });
    });
    this.render();
  },
  methods: {
    isImgFile,
    isAudioFile,
    isVideoFile,
    isTextFile,
    //渲染
    render()
    {
      if(!this.fileUrl){
        return;
      }
      if (this.fileType.indexOf("pdf") != -1)
      {
        // this.getPdfInfo();
       let urlParams = {
           file: this.fileUrl,
           download: true,
           filename: "",
           print: true,
           presentationMode: false,
       };
       this.pdfObj.pdfUrl = buildPDFPreviewUrl(urlParams);
      }
      else if (this.fileType == "docx" || this.fileType == "doc")
      {
        this.getPdfInfo();
      }
      else if (isImgFile("." + this.fileType))
      {

      }
      else if (isAudioFile("." + this.fileType))
      {

      }
      else if (isVideoFile("." + this.fileType))
      {

      }
      if (isTextFile(`.${this.fileType}`))
      {
          this.downloadText();
      }
      else if (this.fileType.indexOf("ofd") != -1)
      {

      }
      else if (this.fileType.indexOf("xls") != -1)
      {

      }
      else if (this.fileType.indexOf("gd") != -1)
      {

      }
      else
      {
      }
    },
    //获取pdf信息
    getPdfInfo()
    {
      this.loading = true;
      let loadingTask = pdf.createLoadingTask(this.fileUrl)

      loadingTask.promise.then(pdf =>
      {
        this.pdfObj.pdfUrl = loadingTask;
        this.pdfObj.numPages = pdf.numPages;
      }).catch(err =>
      {
        console.error('pdf 加载失败', err);
      }).finally(() =>
      {
        setTimeout(() =>
        {
          this.loading = false;
        }, 1000)
      })

    },
    //文件下载
    handleDownload(file)
    {
      let requestParams = {
        url: getOpenDownloadUrl(file.unid),
        method: "get",
        responseType: 'blob'
      };

      let fileName = file.fileName;
      //执行请求
      request(requestParams)
        .then((res) =>
        {
          if (res instanceof Blob)
          {
            this.download(res, fileName);
          }
          else if (res.data instanceof Blob)
          {
            this.download(res.data, fileName);
          }
        })
    },
    //下载
    download(data, fileName)
    {
      if (!data)
      {
        return;
      }
      let url = window.URL.createObjectURL(new Blob([data]));
      let link = document.createElement("a");
      link.style.display = "none";
      link.href = url;
      link.setAttribute("download", fileName);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    },
    //对于text文件 下载
    downloadText()
    {
          let requestParams = {
              url: this.fileUrl,
              method: "get",
              responseType: "blob",
          };
          //执行请求
          request(requestParams).then((res) =>
          {
              let data;
              if (res instanceof Blob)
              {
                  data = res;
              } else if (res.data instanceof Blob)
              {
                  data = res.data;
              }
              if (data)
              {
                  //创建Blob对象
                  let blob = new Blob([data], { type: "text/plain;charset=utf-8" });
                  let tempFile = new File([blob], "test.text", { type: blob.type });
                  let reader = new FileReader(); // 读取TXT起重要作用的
                  reader.readAsText(tempFile, "UTF-8");
                  ///读取文件里面的内容返回
                  let self = this;
                  reader.onload = function (event)
                  {
                      console.log("下载结果", event);
                      self.codeValue = event.target.result;
                      self.refreshCodemirrorKey++;
                  };
              }
          });
      },
    getFileLanguage(filename) {
        const ext = filename.split('.').pop().toLowerCase();
        const languageMap = {
            js: 'javascript',
            jsx: 'javascript',
            ts: 'typescript',
            tsx: 'typescript',
            html: 'html',
            css: 'css',
            less: 'less',
            scss: 'scss',
            json: 'json',
            md: 'markdown',
            vue: 'vue',
            py: 'python',
            java: 'java',
            xml: 'xml',
            sql: 'sql',
        };
        return languageMap[ext] || 'plaintext';
    },
  }
}
</script>

<style lang="scss" scoped>
.preview-box {
  display: flex;
  align-items: center;
  justify-content: center;
}
.img-box{
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.no-preview{
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
